#include "ui_slider.h"
#include "ui_manager.h"

#include "util/timer.h"		    // Needs to come in early
#include "util/mmgr.h"		    // Needs to come in early
#include "util/common_macros.h"		// macros
#include "util/log.h"		    // logging

#include "script/scripthelper.h"
#include "script/write_lua.h"


#ifdef _ENABLE_LUABIND
#include <luabind/luabind.hpp>
#endif // _ENABLE_LUABIND


using namespace ui;
using namespace script;


UISlider::UISlider(UIWidget* pParent,const std::string& Name) :
	UIWidget(pParent, Name),
	m_SliderPos(0.0f)
{
	m_Type = WT_SLIDER;
}

UISlider::~UISlider()
{

}

bool		UISlider::Create(const std::string& Name, const math::Vec2& Pos, const math::Vec2& Size)
{
	UIWidget::Create(Name, Pos, Size);
	// create progress stuff

	return true;
}

bool		UISlider::Load(LuaPlus::LuaObject& _LObj)
{
	UIWidget::Load(_LObj);	// get all the common stuff loaded
	std::string	 Button = ScriptHelper::GetTableString(_LObj, "SliderIcon", "");

	float Progress = ScriptHelper::GetTableFloat(_LObj, "SliderValue", 0.0f);
	SetSlider(Progress);
	m_SliderSize  = ScriptHelper::GetTableVec2(_LObj, "SliderSize", math::Vec2(m_Size.y, m_Size.y));

	if (!Button.empty())
	{
			m_ImageA[WI_BUTTON].Create(	Button, m_BaseUV1, m_BaseUV2, false);
			m_ImageA[WI_BUTTON].Tick(0);
	}
	//m_SliderSize  = m_ImageA[WI_BUTTON].m_Size;
	return true;
}

bool		UISlider::ExportSpecificsToFile(script::WriteLua*	pWL)
{
	pWL->WritePair("SliderValue", GetSlider());
	pWL->WritePair("SliderSize", m_SliderSize);
	if (m_ImageA[WI_BUTTON].IsValid())	pWL->WritePair("SliderIcon", m_ImageA[WI_BUTTON].GetFilename());
	return true;
}


bool		UISlider::Tick(float dt)
{
	m_ImageA[WI_BUTTON].Tick(dt);
	UIWidget::Tick(dt);	// tick children, etc
	return true;
}

bool		UISlider::OnMouseDrag(const math::Vec2& From, const math::Vec2& To)
{
	if (!m_IsActive || !m_IsVisible)
	{
		return false;
	}
	if (IsInside(From))
	{
		// so it's inside? 
		// find the percentage
		float	Delta = To.x  - m_Pos.x;
		SetSlider(Delta / (m_Size.x ));
		TriggerEvent(WE_SLIDER_CHANGE);


		for (ElementList::iterator It = m_Set.begin(); It != m_Set.end(); It++)
		{
			if (It->second->OnMouseDrag(From, To))
				return true;
		}

	}
	return false;
}

bool		UISlider::OnMouseDrop(const math::Vec2& From, const math::Vec2& To, UIWidget* pDroppedWidget)
{
	if (!m_IsActive || !m_IsVisible)
	{
		return false;
	}
	if (IsInside(From))
	{
		// so it's inside? 
		// find the percentage
		float	Delta = To.x  - m_Pos.x;
		SetSlider(Delta / (m_Size.x ));
		TriggerEvent(WE_SLIDER_CHANGE);
		TriggerEvent(WE_LMB_RELEASE);

		for (ElementList::iterator It = m_Set.begin(); It != m_Set.end(); It++)
		{
			if (It->second->OnMouseDrag(From, To))
				return true;
		}

	}
	return false;
}

bool		UISlider::OnMouseDown(const math::Vec2& Pos, unsigned int Button)
{
	/// assume that all children are inside the volume of the parent?
	if (!m_IsActive || !m_IsVisible || !IsInside(Pos))
	{
		return false;
	}

	// so it's inside? 
	// find the percentage
	float	Delta = Pos.x  - m_Pos.x;
	SetSlider(Delta / (m_Size.x));
	TriggerEvent(WE_SLIDER_CHANGE);


	for (ElementList::iterator It = m_Set.begin(); It != m_Set.end(); It++)
	{
		if (It->second->OnMouseDown(Pos, Button))
			return true;
	}

	return false;
}

bool		UISlider::Render(bool Force)
{
	if (!UIWidget::Render(Force)) return false;
	// draw button

	math::Vec2	Pos = m_Pos + math::Vec2((m_Size.x )*m_SliderPos, 0);
	Pos.y += (m_Size.y - m_SliderSize.y)*0.5f;
	Pos.x -= m_SliderSize.x*0.5f;
	m_ImageA[WI_BUTTON].Setup(Pos, m_SliderSize, m_Rotation, m_Scale, m_Color);
	m_ImageA[WI_BUTTON].Render();
	return true;
}

void	UISlider::SetSlider(float f)
{
	if (f < 0.0f)
		f = 0.0f;
	if (f > 1.0f)
		f = 1.0f;
	m_SliderPos = f;
}

UIWidget*	UISlider::GetClone()
{
	UISlider*	pNew = new UISlider(m_pParent, GetCloneName(m_Name));
	FillCloneInfo((UIWidget*)pNew);
	pNew->m_SliderPos		= this->m_SliderPos;
	pNew->m_SliderSize		= this->m_SliderSize;

	return pNew;
}



/// register with LUA Bind
void	UISlider::Register(LuaPlus::LuaState* _pScript)
{
#ifdef _ENABLE_LUABIND
    lua_State * L = _pScript->GetCState ( );

	luabind::module(L)
    [

		luabind::class_<UISlider, UIWidget >( "SliderWidget" )
		.def( "GetSlider",			&UISlider::GetSlider)
		.def( "SetSlider",			&UISlider::SetSlider)
	];
#endif //_ENABLE_LUABIND	
}
